/**
 * 
 */
package view.impl.ingame;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.newdawn.slick.SlickException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import view.impl.ingame.Fighter.Player;



/**
 * @author Julian Lindblad
 *
 */
public class StageLoader {
	
	/**
	 * loadStage loads a given stage defined by the folder. It uses the xml-
	 * file "/structure.xml" as blueprints and dynamicaly builds a stage to use.
	 * 
	 * @param stageFolder The destination to the stage-folder.
	 * @return A loaded stage or null if something went wrong.
	 */
	public static GameStage loadStage(String stageFolder) throws StageLoadException {
			// This code is  based on example code from website: 
			// http://www.developerfusion.com/code/2064/a-simple-way-to-read-an-xml-file-in-java/
			
			GameStage stage;
			
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = null;
			try {
				docBuilder = docBuilderFactory.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				throw new StageLoadException(e);
			}
			Document doc = null;
			try {
				doc = docBuilder.parse(new File(stageFolder + "/structure.xml"));
			} catch (SAXException e) {
				throw new StageLoadException(e);
			} catch (IOException e) {
				throw new StageLoadException(e);
			}
			
			doc.getDocumentElement().normalize();
			
			// Load meta data
			//String idName = doc.getDocumentElement().getAttribute("idName");
			//String prettyName = doc.getDocumentElement().getAttribute("prettyName");
			
			stage = new GameStage();
			
			
			// Load the static images.
			NodeList images = doc.getElementsByTagName("staticImg");
			
			for(int i = 0; i < images.getLength(); i++) {
				Node imageNode = images.item(i);
				if(imageNode.getNodeType() == Node.ELEMENT_NODE) {
					Element image = (Element)imageNode;
					
					// Load image source.
					String src = stageFolder + "/" + image.getAttribute("src");
					
					// Load image position.
					Element posElement = (Element)image.getElementsByTagName("pos").item(0);
					String[] pos = posElement.getChildNodes().item(0).getNodeValue().split(";");
					int posX = Integer.parseInt(pos[0].trim());
					int posY = Integer.parseInt(pos[1].trim());
					
					// Load image size.
					Element sizeElement = (Element)image.getElementsByTagName("size").item(0);
					String[] size = sizeElement.getChildNodes().item(0).getNodeValue().split(";");
					int width = Integer.parseInt(size[0].trim());
					int height = Integer.parseInt(size[1].trim());
					
					// Load depth.
					double depth = Double.parseDouble(image.getAttribute("depth"));
					
					try {
						stage.addGameObject(new StaticImageGameObject(src, 	posX, posY, width, height, depth));
					} catch (SlickException e) {
						throw new StageLoadException("Unable to load game object", e);
					}
				}
			}
			
			// Load character
			Element characterNode = (Element)(doc.getElementsByTagName("character").item(0));
			stage.addFighter(new Fighter(Player.PLAYER1, 
										 Double.parseDouble(characterNode.getAttribute("depth")), 
										 Integer.parseInt(characterNode.getAttribute("groundHeight"))));
			stage.addFighter(new Fighter(Player.PLAYER2, 
					 Double.parseDouble(characterNode.getAttribute("depth")), 
					 Integer.parseInt(characterNode.getAttribute("groundHeight"))));
			
			return stage;
	}
	
}
